local ngx               = ngx
local debug             = debug
local require           = require
local setmetatable      = setmetatable
local assert            = assert
local type              = type
local xpcall            = xpcall
local tostring          = tostring
local ipairs = ipairs
local pairs = pairs

local uu                = require('modules.commhm.utils')
local log               = require('modules.commhm.log')
local ns_lua_ConfigMgr  = require('modules.center_server.luaConfigProxy')
local welfare_code      = require("modules.business_welfare.welfare_code");
local config_check      = require("modules.business_welfare.welfare_config_check")
local config_gen        = require("modules.business_welfare.welfare_config_gen")

local loadstring = loadstring

--需要在reload时生成的配置
local gen_cfg_map = {
    -- 表名 = function
    welfare_gift = config_gen.deal_welf_gift,
    welfare_gift_mall = config_gen.deal_welfare_gift_mall,
    welfare_mount_mall = config_gen.deal_welfare_mount_mall,
    lucky_block = config_gen.deal_lucky_block,
    yin_xiang_card = config_gen.deal_yin_xiang_card,
    welfare_lottery_mall = config_gen.deal_welfare_lottery_mall,
    welfare_lottery_exchange = config_gen.deal_welfare_lottery_exchange,
    welfare_lottery_rewards = config_gen.deal_welfare_lottery_rewards,
    welfare_skin_sale = config_gen.deal_welfare_skin_sale,
}


local FOO = {
    ver_config = {
    	welfare_ver = {
            version_min = 1
        }
    },
    readonly_cfg = {},
    cfg = {},
}

--! @ 将一个table设置为只读table
FOO.readonly = function(t)
    local _m = {
        __index = t,
        __newindex = function()
            assert(false, 'try change readonly cfg' ..t)
        end
    }
    local lock_table = {}
    setmetatable(lock_table, _m)
    return lock_table
end


--! @ 注册配置函数
FOO.OnInit = function()
    ns_lua_ConfigMgr.register_config_file_change('business_item_list', 60, FOO.reload_config, 'welfare_lua_config')
    ns_lua_ConfigMgr.register_config_file_change('business_welfare_config', 60, FOO.reload_config, 'welfare_lua_config')
    ns_lua_ConfigMgr.register_config_file_change('business_advert_config', 60, FOO.reload_config, 'welfare_lua_config')
    ns_lua_ConfigMgr.register_config_file_change('business_def', 60, FOO.reload_config, 'welfare_lua_config')
    ns_lua_ConfigMgr.register_config_file_change('mission', 60, FOO.reload_config, 'welfare_lua_config', 'mission')
    ns_lua_ConfigMgr.register_config_file_change('Act_37', 60, FOO.reload_config, 'welfare_lua_config', "welfare_skin_sale")

   -- 账号服同步的配置解析
   ns_lua_ConfigMgr.register_config_file_change('HeadFrameDef',60, FOO.reload_config_account, 'welfare_lua_config', 'HeadFrameDef')
end


--! @ 获取配置接口
FOO.get_cfg = function(name)
    return FOO.readonly_cfg[name]
end


FOO.get_type_item = function()
    return FOO.readonly_cfg["_type_item_"]
end

--! @ 注册自读配置
FOO.regist_cfg = function(config, name, cfg)
    -- 加载时生成自己服务方便读的配置
    if gen_cfg_map[name] then
        cfg = gen_cfg_map[name](config, cfg)
    end

    FOO.readonly_cfg[name] = {}
    FOO.cfg[name] = cfg
    if type(config) == "table" then
        FOO.readonly_cfg[name] = FOO.readonly(cfg)
    else
        FOO.readonly_cfg[name] = cfg
    end

    --物品表比较大， 按类型查询比较耗时，这里专门针对类型做一次转换
    if name == "itemdef" then
        local type_items = {}
        for id, item in pairs(cfg or {}) do
            if item.ShowType then
                type_items[id] = item
            end
        end
        FOO.readonly_cfg["_type_item_"] = FOO.readonly(type_items)
    end
end


--! @ 加载配置函数
FOO.reload_config = function(content_, table_name)
    local function onLoad()
        assert(content_)
        local tmp_config_ = uu.safe_loadstring(content_)
        local config_  = tmp_config_
        if table_name ~= nil then
            config_ = {}
            config_[table_name] = tmp_config_
        end
        if type(config_) ~= 'table' then
            log.error("error:: config type not table")
        else
            for k, v in pairs(config_) do
                -- 需要检查的配置
                if config_check.check_map[k] then
                    if config_check.check_map[k](v) then
                        FOO.regist_cfg(config_, k, v)
                    else
                        log.error("error:: check cfg fail: tablename = " .. tostring(k))
                    end
                else
                    FOO.regist_cfg(config_, k, v)
                end
                FOO.ver_config[k] = v
            end
        end

        log.day_list("business_welfare_reload", "reload_success", os.date("%Y-%m-%d %H:%M:%S", os.time()))
    end
    xpcall(onLoad, function (errmsg)
        log.error("error::reload_config xpcall failed ,errmsg:".. errmsg )
        log.error( debug.traceback() );
    end)

end

--! @ 加载配置函数
FOO.reload_config_account = function(content_, table_name)
    local function onLoad()
        assert(content_)
        --local config_ = uu.safe_loadstring(content_, nil, table_name)
        local func = loadstring( content_ );
        local config_ = func()
        if type(config_) ~= 'table' then
            log.error("error:: config type not table")
        else
            local config = {}
            config[table_name] = config_
            -- 需要检查的配置
            FOO.regist_cfg(nil, table_name, config[table_name])
        end

        log.day_list("business_welfare_reload", "reload_config_account reload_success", table_name,  os.date("%Y-%m-%d %H:%M:%S", os.time()))
    end
    xpcall(onLoad, function (errmsg)
        log.error("error::reload_config_account xpcall failed ,errmsg:".. errmsg )
        log.error( debug.traceback() );
    end)
end


FOO.version_min_func = function(ver, limit_ver)
    if ver == nil or limit_ver == nil then
        return false
    end

    local ver_ = uu.ver2i(ver)
    local tar_ = uu.ver2i(limit_ver)
    if ver_ and tar_  and  ver_ >= tar_  then
        return true
    end
    return false
end


FOO.version_max_func = function( ver, limit_ver )
    if ver == nil or limit_ver == nil then
        return false
    end

    local ver_ = uu.ver2i(ver)
    local tar_ = uu.ver2i(limit_ver)
    if ver_ and tar_  and  ver_ <= tar_  then
        return true
    end
    return false
end





return FOO
